﻿using System;
using System.Xml;
using System.Xml.XPath;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Util;

namespace InfoJetSoft.Service.Worker
{
	
	//负责处理xsi:nil="true"属性.
	class FormRemoveNilTrueWorker
	{
		
		//一个DatePicker，缺省如下：
		//<my:field1 xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></my:field1>
		//只要在浏览器上打开了表单，用户提交后该元素包含文字，就删除xsi:nil属性。
		//这个处理在通过HTTP参数重新构造XML后调用。
		//不需要像InfoPath一样，当表单中只有一个DatePicker时把xmlns:xsi移动到了my:myFields上，只要保持不动就好了。
		//2008.05.08,在目前的代码中,有三个地方设计到xsi:nil的处理: FormRemoveNilTrueWorker, XFileAttachmentEncoder 和 XImageEncoder.
		//按照目前的顺序,FormRemoveNilTrueWorker先被调用.
		public static void  removeNilTrue(Form form)
		{
			//如果记录了NillableDateSchemaTypeTable.
			if( form.Manifest.NillableSchemaTypeTable != null )
			{
				XmlElement root = form.XmlDoc.DocumentElement;
				//找到所有的元素.
				XmlNodeList elementList = DOMUtil.selectNodes(root, "//*", 0, form.XmlNsResolver);
				foreach( XmlElement element in elementList )
				{
					//如果这是一个nillable为true的date类型元素.
					//由于SchemaTypeWorker.findSchemaType()的缺陷,目前不能处理所有的SchemaType,但是对于使用InfoPath设计的form schema是没有问题的.
					SchemaType schemaType = (SchemaType)form.Manifest.NillableSchemaTypeTable[ element.Name ];
					if( schemaType != null )
					{
						if( element.InnerText.Trim().Length > 0 )
						{
							//如果有内容,去掉xsi:nil属性.
							element.RemoveAttribute( "nil", JetConstant.URI_XSI );
						}
						else
						{
							//如果无内容,添加xsi:nil="true"属性.
							XmlAttribute nilAttr = form.XmlDoc.CreateAttribute( "xsi", "nil", JetConstant.URI_XSI );
							nilAttr.Value = "true";
							element.SetAttributeNode( nilAttr );
						}
					}
					else
					{
						//这里还没有处理的类型是unknown,如xml_value.xsn中的token.
						//输入后xmlns:xsi仍然保留,所以如果有内容remove xsi:nil,但是没有处理无内容由添加xsi:nil的情况.
						if( element.InnerText.Trim().Length > 0 )
						{
							//如果有内容,去掉xsi:nil属性.
							element.RemoveAttribute( "nil", JetConstant.URI_XSI );
						}
					}
				}
			}
		}
	}
}